package com.ruoyi.chargepile.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.chargepile.domain.*;
import com.ruoyi.chargepile.domain.dto.ChargeRecordsAddDto;
import com.ruoyi.chargepile.domain.dto.ChargeRecordsDto;
import com.ruoyi.chargepile.domain.enums.*;
import com.ruoyi.chargepile.domain.vo.ChargeRecordsVo;
import com.ruoyi.chargepile.mapper.*;
import com.ruoyi.chargepile.service.*;
import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.quartz.domain.SysJob;
import com.ruoyi.quartz.service.ISysJobService;
import com.ruoyi.util.DateRange;
import com.ruoyi.util.Pages;
import org.quartz.SchedulerException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * <p>
 * 充电记录表 服务实现类
 * </p>
 *
 * @author zxc
 * @since 2024-07-03
 */
@Service
public class ChargeRecordsServiceImpl extends ServiceImpl<ChargeRecordsMapper, ChargeRecords> implements ChargeRecordsService {

    @Autowired
    private ChargeRecordsService chargeRecordsService;

    @Autowired
    private ChargePileService chargePileService;

    @Autowired
    private OrdersService ordersService;

    @Autowired
    private PointsService pointsService;

    @Autowired
    private PointsRecordsService pointsRecordsService;

    @Autowired
    private ISysJobService iSysJobService;

    @Resource
    private ChargeRecordsMapper chargeRecordsMapper;

    @Resource
    private ChargePileMapper chargePileMapper;

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private PointsMapper pointsMapper;

    @Resource
    private PointsRecordsMapper pointsRecordsMapper;



    @Override
    public List<ChargeRecordsVo> listChargeRecordsVo(Pages pages, DateRange dateRange, DateRange dateRangePay, ChargeRecordsDto chargeRecordsDto) {
        return chargeRecordsMapper.listChargeRecordsVo(pages, dateRange, dateRangePay, chargeRecordsDto);
    }

    @Override
    public AjaxResult addChargeRecords(ChargeRecordsAddDto chargeRecordsAddDto) {
        ChargeRecords chargeRecords = new ChargeRecords();
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        BeanUtils.copyProperties(chargeRecordsAddDto, chargeRecords);

        chargeRecords.setUserId(Math.toIntExact(sysUser.getUserId()));
        chargeRecords.setChargeStartTime(new Date());
        chargeRecords.setChargeStatus(ChargeRecordsStatusEnum.IN_USE.getCode());

        LocalDateTime localDateTime = LocalDateTime.now();
        BigDecimal chargeTime = chargeRecordsAddDto.getChargeTime();
        // 整数部分
        BigDecimal integerPart = chargeTime.setScale(0, RoundingMode.DOWN);
        // 小数部分
        BigDecimal fractionalPart = chargeTime.subtract(integerPart);
        BigDecimal multiply = fractionalPart.multiply(BigDecimal.valueOf(60));

        LocalDateTime localDateTime1 = localDateTime.plusHours(integerPart.longValue());
        LocalDateTime localDateTime2 = localDateTime1.plusMinutes(multiply.longValue());
        chargeRecords.setChargeEndTime(localDateTime2);

        ChargePile chargePile = chargePileMapper.selectById(chargeRecordsAddDto.getChargePileId());
        chargePile.setStatus(ChargePileStatusEnum.IN_USE.getCode());

        // 更新充电桩状态
        chargePileMapper.updateById(chargePile);
        // 插入充电记录
        chargeRecordsMapper.insert(chargeRecords);

        Orders orders = new Orders();
        orders.setChargeRecordsId(chargeRecords.getId());
        orders.setCreatedTime(new Date());
        orders.setPaymentAmount(chargeRecordsAddDto.getPayment());
        orders.setPaymentMethod(PaymentMethodEnum.WECHAT_PAY.getCode());
        String formattedChargeRecordsId = String.format("%06d", chargeRecords.getId());
        String formattedUserId= String.format("%03d", sysUser.getUserId());
        orders.setOrdersNumber(chargePile.getNumber() + "-" + formattedChargeRecordsId + "-" + formattedUserId);
        // 插入订单
        ordersMapper.insert(orders);

        // 返现积分
        PointsRecords getPoints = new PointsRecords();
        BigDecimal point = new BigDecimal(0);
        Random rand = new Random();
        if(chargeRecordsAddDto.getPayment().intValue() > 0){
            int gets = rand.nextInt(chargeRecordsAddDto.getPayment().intValue());
            getPoints.setPointsType(PointsTypeEnum.GETS.getCode());
            getPoints.setCreatedTime(new Date());
            getPoints.setOrdersId(orders.getId());
            getPoints.setUserId(Math.toIntExact(sysUser.getUserId()));
            getPoints.setPointsChange(BigDecimal.valueOf(gets));
            pointsRecordsMapper.insert(getPoints);
            point.add(getPoints.getPointsChange());
        }


        // 消费积分
        if((chargeRecordsAddDto.getPointBalance() != null) && !(chargeRecordsAddDto.getPointBalance().compareTo(BigDecimal.valueOf(0)) == 0) ){
            PointsRecords consumePoints = new PointsRecords();
            consumePoints.setPointsType(PointsTypeEnum.CONSUME.getCode());
            consumePoints.setCreatedTime(new Date());
            consumePoints.setOrdersId(orders.getId());
            consumePoints.setUserId(Math.toIntExact(sysUser.getUserId()));
            consumePoints.setPointsChange(chargeRecordsAddDto.getPointBalance());
            point.subtract(consumePoints.getPointsChange());
            pointsRecordsMapper.insert(consumePoints);
        }

        QueryWrapper<Points> pointsQueryWrapper = new QueryWrapper<>();
        pointsQueryWrapper
                .lambda()
                .eq(Points::getUserId, sysUser.getUserId());
        Points points = pointsMapper.selectOne(pointsQueryWrapper);
        points.setPointBalance(point.intValue() + points.getPointBalance());
        pointsMapper.updateById(points);

        SysJob sysJob = new SysJob();
        sysJob.setJobId(Long.valueOf(chargeRecords.getId()));
        sysJob.setJobName(chargePile.getId() + "正在充电");
        sysJob.setJobGroup(SysJobGroupEnum.DEFAULT.getCode());
        sysJob.setInvokeTarget("changePileStatusTask.changePileStatus(" + chargeRecords.getId() +")");
        sysJob.setCronExpression(localDateTime2.getSecond() + " " + localDateTime2.getMinute() + " " + localDateTime2.getHour() + " " + localDateTime2.getDayOfMonth() + " * ? *");
        sysJob.setMisfirePolicy(ScheduleConstants.MISFIRE_FIRE_AND_PROCEED);
        sysJob.setConcurrent(SysJobConcurrentEnum.YES.getCode());
        sysJob.setStatus(SysJobStatusEnum.PAUSE.getCode());
        System.out.println("+++++++++++++++++++++++++++++++++");
        System.out.println("执行时间" + sysJob.getCronExpression());
        System.out.println("+++++++++++++++++++++++++++++++++");
        if(iSysJobService.checkCronExpressionIsValid(sysJob.getCronExpression())){
            try {
                iSysJobService.insertJob(sysJob);
                iSysJobService.resumeJob(sysJob);
            } catch (SchedulerException e) {
                e.printStackTrace();
            } catch (TaskException e) {
                e.printStackTrace();
            }
        }else{
            return AjaxResult.error("cron表达式错误");
        }


        return AjaxResult.success();
    }
}
